package com.sy.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.sy.bean.JedisConfig;
import com.sy.config.RedisClient;
import com.sy.constant.AppConstant;
import com.sy.dto.Result;
import com.sy.entity.*;
import com.sy.exception.ShopSystemException;
import com.sy.interfaces.KillService;
import com.sy.mapper.OrderMapper;
import com.sy.mapper.OrderProductRefMapper;
import com.sy.mapper.ProductMapper;
import com.sy.mapper.SeckKillMapper;
import com.sy.service.SeckKillService;
import com.sy.service.UserService;
import com.sy.vo.OrderItemParam;
import org.apache.commons.lang.StringUtils;
import org.redisson.RedissonClient;
import org.redisson.core.RLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.sql.Date;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @Description:
 * @Param:
 * @return:
 * @Author: 朱天宇
 * @Date:
 */
@Service
public class SeckKillServiceImpl implements SeckKillService , KillService {
    @Autowired
    private SeckKillMapper seckKillMapper;
    @Autowired
    private RedissonClient redisson;
    @Autowired
    private JedisConfig jedisConfig;
    @Autowired
    private UserService userService;
    @Autowired
    private RedisClient redisClient;
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private OrderProductRefMapper orderProductRefMapper;
    @Autowired
    private ProductMapper productMapper;
    @Override
    public List<Product> getProductsCanKill() {
        return seckKillMapper.getSeckKillProducts();
    }


    @Override
    public Result startKillTime(Integer pid,String token){
        System.out.println(redisson);
        RLock rLock = redisson.getLock("kucun");
        Result result=new Result();
        try {
            //上锁
            rLock.lock();
            User user = userService.LoginUser(token);
            Integer uid = user.getId();
            System.out.println("当前用户id是"+uid);
            String ku = jedisConfig.getString(AppConstant.activity_Redis_Key_Prefix+pid);
            if (ku.equals(String.valueOf(0))){
                System.out.println("库存已经0了别再发送请求了");
                throw new Exception("库存已无");
            }
            SeckKill isKill = seckKillMapper.getIsKill(pid, uid);
            if (isKill==null) {
                //说明此人未参加过此活动
                OrderItemParam orderItemParam=new OrderItemParam();
                orderItemParam.setCount(1);
                orderItemParam.setPid(pid);
                orderItemParam.setFlavor("1");
                orderItemParam.setPackaging("1");
                List<OrderItemParam> list=new ArrayList<>();
                list.add(orderItemParam);

                Integer integer = generateOrder(token, list);

                seckKillMapper.updateKillCount(pid);//数据库库存减一
                seckKillMapper.addActivityUser(pid,uid);
                jedisConfig.decrBy(AppConstant.activity_Redis_Key_Prefix+pid);
                result.setCode(200);
                result.setData(integer);
            }else{
                result.setCode(600);
                throw new Exception("不能再次秒杀");
            }
        }catch (Exception e){
            e.printStackTrace();
            result.setCode(600);
            result.setError(e.getMessage());
        }
        finally {
            //解锁
            rLock.unlock();
        }
        return result;
    }
    @Override
    public Result getCanKillProducts() {
        List<Product> seckKillProducts = seckKillMapper.getSeckKillProducts();
        Result result=new Result();
        if (CollectionUtils.isEmpty(seckKillProducts)){
            result.setCode(404);
            result.setError("无活动");
        }else {
            result.setCode(200);
            result.setData(seckKillProducts);
        }
        return result;
    }


    private Integer  generateOrder(String token,List<OrderItemParam> orderItemParams){
        Result result = new Result();
        try {
            User user = userService.LoginUser(token);
            String redisTimerKey = AppConstant.SUBMIT_ORDER_TIMER_PREFIX + user.getId();
            String redisTimer =jedisConfig.getString(redisTimerKey);
            if (StringUtils.isNotBlank(redisTimer)) {
                throw new ShopSystemException("订单提交过于频繁，请稍后再试");
            }
            else {
                redisClient.set(redisTimerKey, user.getId());
                jedisConfig.expire(redisTimerKey, AppConstant.SUBMIT_ORDER_TIME_INTERVAL);
            }
            BigDecimal multiply = new BigDecimal(0);
            Order order = new Order();
            order.setOrdertime(new Date(System.currentTimeMillis()));
            order.setStatus("2");
            order.setUid(user.getId());
            Set<String> set=new HashSet<>();
            StringBuilder stringBuilder=new StringBuilder();
            for (OrderItemParam orderItemParam:orderItemParams){
                Integer count = orderItemParam.getCount();
                Integer pid = orderItemParam.getPid();
                Product product = productMapper.selectById(pid);
                String productname = product.getProductname();
                if(set.add(productname)){//说明加成功了
                    stringBuilder.append(productname).append(",");
                }
                multiply.add(product.getPresentprice().multiply(new BigDecimal(count)));
            }
            String oidNo = redisClient.generateOrderId();
            String s = stringBuilder.toString();
            order.setProductname(s.substring(0,s.length()-1));
            order.setOrderno(oidNo);
            order.setQuantity(orderItemParams.size());
            order.setTotalprice(multiply);
            orderMapper.insert(order);
            QueryWrapper<Order> orderQueryWrapper = new QueryWrapper<>();
            orderQueryWrapper.eq("orderNo",oidNo);
            Integer orderId = orderMapper.selectOne(orderQueryWrapper).getId();
            for (OrderItemParam orderItemParam:orderItemParams){
                String flavor = orderItemParam.getFlavor();
                String packaging = orderItemParam.getPackaging();
                Integer pid = orderItemParam.getPid();
                Integer count = orderItemParam.getCount();
                OrderProductRef orderProductRef= new OrderProductRef();
                orderProductRef.setCount(count);
                orderProductRef.setFid(Integer.parseInt(flavor));
                orderProductRef.setPackid(Integer.parseInt(packaging));
                orderProductRef.setPid(pid);
                orderProductRef.setOid(orderId);
                orderProductRefMapper.insert(orderProductRef);
            }
         return orderId;
        } catch (Exception e) {
            e.printStackTrace();
            result.setError(e.getMessage());
            result.setCode(500);
        }
        return null;

    }

}
